package com.ruoyi.web.controller.equ;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.equ.domain.EquAsset;
import com.ruoyi.equ.domain.EquMove;
import com.ruoyi.equ.domain.EquRepair;
import com.ruoyi.equ.domain.vo.EquRepairVo;
import com.ruoyi.equ.domain.vo.EquRepairVos;
import com.ruoyi.equ.service.IEquAssetService;
import com.ruoyi.equ.service.IEquRepairService;
import com.ruoyi.system.domain.SysNotice;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysNoticeService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;


import jakarta.servlet.http.HttpServletResponse;

import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


/**
 * 维修工单Controller
 *
 * @author ruoyi
 * @date 2025-11-05
 */
@RestController
@RequestMapping("/equ/repair")
public class EquRepairController extends BaseController {
    @Autowired
    private IEquRepairService equRepairService;

    @Autowired
    private IEquAssetService equAssetService;

    @Autowired
    private ISysNoticeService noticeService;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private ISysUserService userService;

    //常量定义
    private static final String REPAIR_NOTICE_TITLE = "维修工单处理提醒";
    private static final String DEPT_OVERTIME_TITLE = "维修工单处理超时提醒";

    /**
     * 查询维修工单列表
     */
    @PreAuthorize("@ss.hasPermi('equ:repair:list')")
    @GetMapping("/list")
    public TableDataInfo list(@ModelAttribute EquRepair equRepair) {
        startPage();
        List<EquRepair> list = equRepairService.selectEquRepairList(equRepair);
        return getDataTable(list);
    }
    /**
     * 查询维修工单列表
     */
    @PreAuthorize("@ss.hasPermi('equ:repair:list')")
    @GetMapping("/listVo")
    public TableDataInfo listVo(EquRepairVos equRepair)
    {
        startPage();
        List<EquRepairVos> list = equRepairService.selectEquRepairVoList(equRepair);
        return getDataTable(list);
    }
    /**
     * 查询维修工单列表（最近3条）
     */
    @PreAuthorize("@ss.hasPermi('equ:repair:list')")
    @GetMapping("/listThree")
    public AjaxResult listThree(@ModelAttribute EquRepair equRepair) {
        return success(equRepairService.selectEquRepairListThree(equRepair));
    }

    /**
     * 导出维修工单列表
     */
    @PreAuthorize("@ss.hasPermi('equ:repair:export')")
    @Log(title = "维修工单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, @ModelAttribute EquRepair equRepair) {
        List<EquRepair> list = equRepairService.selectEquRepairList(equRepair);
        ExcelUtil<EquRepair> util = new ExcelUtil<EquRepair>(EquRepair.class);
        util.exportExcel(response, list, "维修工单数据");
    }

    /**
     * 获取维修工单详细信息
     */
    @PreAuthorize("@ss.hasPermi('equ:repair:query')")
    @GetMapping(value = "/{repairId}")
    public AjaxResult getInfo(@PathVariable("repairId") Long repairId) {
        return success(equRepairService.selectEquRepairByRepairId(repairId));
    }

    /**
     * 新增维修工单
     */
    @PreAuthorize("@ss.hasPermi('equ:repair:add')")
    @Log(title = "维修工单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody EquRepair equRepair) {
        return toAjax(equRepairService.insertEquRepair(equRepair));
    }

    /**
     * 修改维修工单
     */
    @PreAuthorize("@ss.hasPermi('equ:repair:edit')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody EquRepair equRepair) {
        return toAjax(equRepairService.updateEquRepair(equRepair));
    }

    /**
     * 删除维修工单
     */
    @PreAuthorize("@ss.hasPermi('equ:repair:remove')")
    @Log(title = "维修工单", businessType = BusinessType.DELETE)
    @DeleteMapping("/{repairIds}")
    public AjaxResult remove(@PathVariable("repairIds") Long[] repairIds) {
        return toAjax(equRepairService.deleteEquRepairByRepairIds(repairIds));
    }

    /**
     * 1.7 新增维修工单记录
     */
    @PreAuthorize("@ss.hasPermi('equ:repair:addRepair')")
    @Log(title = "维修工单", businessType = BusinessType.INSERT)
    @PostMapping("/addRepair")
    public AjaxResult addRepair(@RequestBody EquRepair equRepair) {
        Boolean result = equRepairService.addRepair(equRepair);

        if (result) {
            return AjaxResult.success(result);
        } else {
            return AjaxResult.error("操作失败");
        }
    }


    /**
     * 2.3修改维修状态及资产状态(维修中)
     */
    @PreAuthorize("@ss.hasPermi('equ:repair:edit')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @Transactional(rollbackFor = Exception.class) // 事务控制，确保操作原子性
    @PutMapping("/updateRepairAndAssetAndAddNotice")
    public AjaxResult updateRepairAndAssetAndAddNotice(@RequestBody EquRepairVo equRepair) {   //equRepairVo需要哪些字段  repairId assetId isNervous 维修负责人id(userId)
        if (equRepair.getRepairId() == null) {
            return error("请选择工单");
        }
//        //获取发布人id
//        Long publishId = SecurityUtils.getUserId();
//        //获取发布人名称
//        String publishName = SecurityUtils.getUsername();
        //获取资产id
        Long assetId = equRepair.getAssetId();

        //获取维修负责人id
        Long userId = equRepair.getUserId();
        String userName = userService.selectUserById(userId).getUserName();
        Long deptId = userService.selectUserById(userId).getDeptId();
        String leader = deptService.selectDeptById(deptId).getLeader();
        Long leaderId = userService.selectUserByUserName(leader).getUserId();
        //创建定时任务
        ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
        // 工单处理中状态
        String ORDER_STATUS_PROCESSING = "维修中";
        long initialDelay = 0; // 初始延迟：0分钟（立即开始第一次执行）
        long period = 30;      // 执行周期：30分钟
        long totalDuration = 120; // 总执行时长：2小时
        TimeUnit timeUnit = TimeUnit.MINUTES; // 时间单位：分钟
        //修改维修工单状态
        equRepair.setOrderStatus(ORDER_STATUS_PROCESSING);
        //修改资产设备状态
        EquAsset equAsset = equAssetService.selectEquAssetByAssetId(assetId);
        equAsset.setAssetStatus(ORDER_STATUS_PROCESSING);
        equAssetService.updateEquAsset(equAsset);
        //获取通知对象
        SysNotice notice = new SysNotice();
        notice.setPublishId(0L);
        notice.setPublishName("系统");
        //线程池，紧急工单，注意判断工单是否响应(该工单状态变为维修中)
        if (equRepair.getNervous()) {
            // 30分钟后执行逻辑 提醒维修负责人
            scheduler.scheduleAtFixedRate(() -> {
                //查询状态是否响应
                EquRepair equRepair1 = equRepairService.selectEquRepairByRepairId(equRepair.getRepairId());
                if (equRepair1.getOrderStatus().equals("已完成")) {
                    scheduler.shutdown();
                } else {
                    notice.setAcceptId(userId);
                    notice.setNoticeTitle(REPAIR_NOTICE_TITLE);
                    notice.setNoticeContent("工单编号：" + equRepair.getRepairId() + "，请及时处理！");
                    noticeService.insertNotice(notice);
                }
            }, initialDelay, period, timeUnit);
            // 2小时后执行逻辑 提醒部门负责人
            scheduler.schedule(() -> {
                EquRepair equRepair1 = equRepairService.selectEquRepairByRepairId(equRepair.getRepairId());
                if (equRepair1.getOrderStatus().equals("已完成")) {
                    //关闭线程池
                    scheduler.shutdown();
                } else {
                    notice.setAcceptId(leaderId);
                    notice.setNoticeTitle(DEPT_OVERTIME_TITLE);
                    notice.setNoticeContent("工单编号：" + equRepair.getRepairId() +
                            "处理超时，部门负责人请及时联系维修负责人:" + userName);
                    noticeService.insertNotice(notice);
                }
            }, totalDuration, timeUnit);
        }

        return toAjax(equRepairService.updateEquRepair(equRepair));
    }

    /**
     * 2.5修改维修状态及资产状态(已完成)
     */
    @PreAuthorize("@ss.hasPermi('equ:repair:edit')")
    @Log(title = "维修工单", businessType = BusinessType.UPDATE)
    @PutMapping("/finishRepairAndAsset")
    public AjaxResult finishRepairAndAsset(@RequestBody EquRepair equRepair) {   //equRepairVo需要哪些字段  repairId assetId
        if (equRepair.getRepairId() == null) {
            return error("请选择工单");
        }
        // equRepair需要哪些字段 assetId repairId
        Long assetId = equRepair.getAssetId();

        //修改维修工单状态
        equRepair.setOrderStatus("已完成");
        equRepair.setCloseTime(new Date());

        //修改资产设备状态
        EquAsset equAsset = equAssetService.selectEquAssetByAssetId(assetId);
        equAsset.setAssetStatus("正常");
        equAssetService.updateEquAsset(equAsset);


        return toAjax(equRepairService.updateEquRepair(equRepair));
    }
    /**
     * 获取维修记录详细信息
     * @param assetId
     * @return List<EquRepair>
     */
    @PreAuthorize("@ss.hasPermi('equ:move:list')")
    @GetMapping(value = "/getRepairByAssetId/{assetId}")
    public TableDataInfo getRepairByAssetId(@PathVariable("assetId") Long assetId)
    {
        startPage();
        List<EquRepair> list = equRepairService.getRepairsByAssetId(assetId);
        return getDataTable( list);
    }

}
